
package com.qcadoo.mes.productionCounting.validators;

import com.google.common.collect.Sets;
import com.qcadoo.mes.orders.constants.OrderFields;
import com.qcadoo.mes.orders.states.constants.OrderStateStringValues;
import com.qcadoo.mes.productionCounting.ProductionCountingService;
import com.qcadoo.mes.productionCounting.constants.OrderFieldsPC;
import com.qcadoo.mes.productionCounting.constants.ProductionTrackingFields;
import com.qcadoo.mes.productionCounting.constants.TypeOfProductionRecording;
import com.qcadoo.mes.productionCounting.states.constants.ProductionTrackingStateStringValues;
import com.qcadoo.model.api.DataDefinition;
import com.qcadoo.model.api.Entity;
import com.qcadoo.model.api.search.SearchRestrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Set;

@Service
public class ProductionTrackingValidators {

    private static final Set<String> L_ORDER_STARTED_STATES_SET = Sets.newHashSet(OrderStateStringValues.IN_PROGRESS,
            OrderStateStringValues.INTERRUPTED, OrderStateStringValues.COMPLETED);

    @Autowired
    private ProductionCountingService productionCountingService;

    public boolean validatesWith(final DataDefinition productionTrackingDD, final Entity productionTracking) {
        Entity order = productionTracking.getBelongsToField(ProductionTrackingFields.ORDER);

        boolean isValid = true;

        isValid = isValid && checkTypeOfProductionRecording(productionTrackingDD, productionTracking, order);
        //isValid = isValid && willOrderAcceptOneMore(productionTrackingDD, productionTracking, order);
        isValid = isValid && checkIfOrderIsStarted(productionTrackingDD, productionTracking, order);
        isValid = isValid && checkTimeRange(productionTrackingDD, productionTracking);
        isValid = isValid && checkIfOperationIsSet(productionTrackingDD, productionTracking);

        return isValid;
    }

    private boolean checkIfOperationIsSet(final DataDefinition productionTrackingDD, final Entity productionTracking) {
        String recordingMode = productionTracking.getBelongsToField(ProductionTrackingFields.ORDER).getStringField(
                OrderFieldsPC.TYPE_OF_PRODUCTION_RECORDING);
        Object orderOperation = productionTracking.getField(ProductionTrackingFields.TECHNOLOGY_OPERATION_COMPONENT);

        if (TypeOfProductionRecording.FOR_EACH.getStringValue().equals(recordingMode) && orderOperation == null) {
            productionTracking.addError(productionTrackingDD.getField(ProductionTrackingFields.TECHNOLOGY_OPERATION_COMPONENT),
                    "productionCounting.productionTracking.messages.error.operationIsNotSet");
            return false;
        }
        return true;

    }

    private boolean checkTimeRange(final DataDefinition productionTrackingDD, final Entity productionTracking) {
        Date timeRangeFrom = productionTracking.getDateField(ProductionTrackingFields.TIME_RANGE_FROM);
        Date timeRangeTo = productionTracking.getDateField(ProductionTrackingFields.TIME_RANGE_TO);

        if (timeRangeFrom == null || timeRangeTo == null || timeRangeTo.after(timeRangeFrom)) {
            return true;
        }
        productionTracking.addError(productionTrackingDD.getField(ProductionTrackingFields.TIME_RANGE_TO),
                "productionCounting.productionTracking.productionTrackingError.timeRangeToBeforetumeRangeFrom");
        return false;
    }

    private boolean checkTypeOfProductionRecording(final DataDefinition productionTrackingDD, final Entity productionTracking,
                                                   final Entity order) {
        if (order == null) {
            return true;
        }
        final String typeOfProductionRecording = order.getStringField(OrderFieldsPC.TYPE_OF_PRODUCTION_RECORDING);

        return isValidTypeOfProductionRecording(productionTrackingDD, productionTracking, typeOfProductionRecording);
    }

    private boolean isValidTypeOfProductionRecording(final DataDefinition productionTrackingDD, final Entity productionTracking,
                                                     final String typeOfProductionRecording) {
        boolean isValid = true;

        if (productionCountingService.checkIfTypeOfProductionRecordingIsEmptyOrBasic(typeOfProductionRecording)) {
            productionTracking.addError(productionTrackingDD.getField(ProductionTrackingFields.ORDER),
                    "productionCounting.validate.global.error.productionTracking.orderError");
            isValid = false;
        }
        if (productionCountingService.isTypeOfProductionRecordingBasic(typeOfProductionRecording)) {
            productionTracking.addError(productionTrackingDD.getField(ProductionTrackingFields.ORDER),
                    "productionCounting.productionTracking.report.error.orderWithBasicProductionCounting");
            isValid = false;
        }

        return isValid;
    }



    private boolean checkIfOrderIsStarted(final DataDefinition productionTrackingDD, final Entity productionTracking,
                                          final Entity order) {
        boolean isStarted = true;

        String state = productionTracking.getStringField(ProductionTrackingFields.STATE);
        String orderState = order.getStringField(OrderFields.STATE);

        if (isProductionTrackingDraft(state) && !isOrderStateStarted(orderState)) {
            productionTracking.addError(productionTrackingDD.getField(ProductionTrackingFields.ORDER),
                    "productionCounting.productionTracking.messages.error.orderIsNotStarted");

            isStarted = false;
        }

        return isStarted;
    }

    private boolean isProductionTrackingDraft(final String state) {
        return ProductionTrackingStateStringValues.DRAFT.equals(state);
    }

    private boolean isOrderStateStarted(final String orderState) {
        return L_ORDER_STARTED_STATES_SET.contains(orderState);
    }

}
